package com.nulldev.util.string;

import com.nulldev.util.java.DataSet;
import com.nulldev.util.math.MathUtil;

public class UnicodeUtils {

	public static final CharSequenceTranslator JAVA = new LookupTranslator((CharSequence[][])new String[][] { { "\"", "\\\"" }, { "\\", "\\\\" } }).with(new LookupTranslator((CharSequence[][])TranslationArrays.JAVA_CTRL_CHARS_ESCAPE())).with(JUEscaper.outsideOf(32, 127));;
	public static final CharSequenceTranslator UNESCAPE_JAVA = new AggregateTranslator(new CharSequenceTranslator[] { new OctalUnescaper(), new UnicodeUnescaper(), new LookupTranslator((CharSequence[][])TranslationArrays.JAVA_CTRL_CHARS_UNESCAPE()), new LookupTranslator((CharSequence[][])new String[][] { { "\\\\", "\\" }, { "\\\"", "\"" }, { "\\'", "'" }, { "\\", "" } }) });

	public static String escape(final String input) {
	    final StringBuilder b = new StringBuilder();

	    for (char c : input.toCharArray()) {
	        if (c >= 128)
	            b.append("\\u").append(String.format("%04X", (int) c));
	        else
	            b.append(c);
	    }

	    return b.toString();
	}

	public static String escapeFull(final String input) {
	    final StringBuilder b = new StringBuilder();

	    for (char c : input.toCharArray()) {
	    	b.append("\\u").append(String.format("%04X", (int) c));
	    }

	    return b.toString();
	}

    public static final String unescapeJava(final String input) {
        return UnicodeUtils.UNESCAPE_JAVA.translate(input);
    }

    public static final String escapeJava(final String input) {
        return JAVA.translate(input);
    }

    public static boolean isAscii(char ch) {
        return ch < 128;
    }

    public static boolean isSafe(final char ch) {
    	return Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.BASIC_LATIN;
    }

	public static void println(final String data) {
		System.out.println(escapeFull(data));
	}
	
	public static void printA(final String data) {
		final String[] vals = StringsUtil.byLineSepeartor(data);
		for (final String val : vals) {
			System.out.println(escapeFull(val) + " | " + val);
		}
	}

	public static boolean isSafe(final String data) {
		for (final char c : data.toCharArray()) {
			if (!isAscii(c)) {
				return false;
			}
		}
		return true;
	}

	public static String toSafe(final String input) {
		final StringBuilder out = new StringBuilder();
		for (final char c : input.toCharArray()) {
			if (isSafe(c)) {
				out.append(c);
			}
		}
		return out.toString();
	}

	public static char randomChar() {
		return (char) MathUtil.randInt(128, 65535);
	}

	public static boolean isValidSequence(char[] a) {
		for (int i = 0; i < a.length; i++) {
			if (Character.isHighSurrogate(a[i])) {
				if (i < a.length - 1 && Character.isLowSurrogate(a[i + 1])) {
					i++;
				} else {
					return false;
				}
			} else if (Character.isLowSurrogate(a[i])) {
				return false;
			}
		}
		return true;
	}

	public static boolean hasUTF16Chars(final String t) {
		return isValidSequence(t.toCharArray());
	}
}
